package view.library
{
	import events.library.EventCreateNewLibraryItem;
	import events.library.EventRemoveLibraryItems;
	import events.library.EventSetLibraryItemProperty;
	
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.utils.setTimeout;
	
	import model.ModelLibrary;
	import model.ModelRooms;
	
	import mx.binding.utils.BindingUtils;
	import mx.collections.ArrayCollection;
	import mx.controls.Alert;
	import mx.core.UIComponent;
	import mx.events.CloseEvent;
	import mx.events.FlexEvent;
	
	import org.flashIso.engine.base.IsoMap;
	import org.flashIso.engine.base.IsoPerspective;
	import org.flashIso.engine.library.objects.LTile;
	import org.flashIso.engine.objects.IsoTile;
	import org.robotlegs.mvcs.Mediator;
	
	import others.Util;
	
	import spark.events.IndexChangeEvent;
	
	
	public class MediatorScreenTiles extends Mediator
	{
		[Inject]
		public var v:ScreenTiles;
		
		[Inject]
		public var modelLibrary:ModelLibrary;
		
		[Inject]
		public var mr:ModelRooms;
		
		
		private var lObjectControls:Array;
		private var objectControls:Array;
		
		private var isoMap:IsoMap = new IsoMap();
		private var isoTile:IsoTile = new IsoTile();
		
		override public function onRegister() : void  {
			v.list.dataProvider = modelLibrary.tilesDataProvider;
			v.imagesList.dataProvider = modelLibrary.imagesDataProvider;
			
			lObjectControls = [v.xSize, v.ySize, v.zSize, v.deltaX, v.deltaY, v.deltaZ, v.fillAlpha, v.fillColor, v.lineAlpha, v.
				lineColor, v.lineThickess, v.checkBoxUseFramesWhenRotating, v.
				imagesList, v.imageX, v.imageY, v.imageScaleX, v.imageScaleY, v.imageRotation, v.imageAlpha,
				v.elevationEast, v.elevationNorth, v.elevationSouth, v.elevationWest, v.drawShape, v.hitAreaType];
			objectControls = [];
			var i:uint;
			for (i = 0; i < lObjectControls.length; i++){
				eventMap.mapListener(lObjectControls[i], Event.CHANGE, lObjectPropertyChange, Event);
				eventMap.mapListener(lObjectControls[i], FlexEvent.VALUE_COMMIT, lObjectPropertyChange, Event);
			}
			for (i = 0; i < objectControls.length; i++){
				eventMap.mapListener(objectControls[i], Event.CHANGE, objectPropertyChange, Event);
			}
			
			eventMap.mapListener(v.btnCreateTile, MouseEvent.CLICK, btnCreateObject, MouseEvent);
			eventMap.mapListener(v.btnDeleteTile, MouseEvent.CLICK, btnRemoveObject, MouseEvent);
			eventMap.mapListener(v.list, IndexChangeEvent.CHANGE, listSelectionChange, IndexChangeEvent);
			
			v.container.sprite = isoMap;
			isoMap.addElement(isoTile);
			isoMap.visible = false;		
			BindingUtils.bindSetter(setPerspective, mr, "currentPerspective", false, false);

			eventMap.mapListener(v.elevation, Event.CHANGE, elevationChangeHandler);

		}
		
		private function elevationChangeHandler(e:Event) : void{
			var lTile:LTile = v.list.selectedItem;
			v.elevationEast.value = v.elevationNorth.value = v.elevationSouth.value = v.elevationWest.value = v.elevation.value;
		}
		
		private function updateElevationControl() : void {
			var lTile:LTile = v.list.selectedItem;
			if (lTile != null) {
				v.elevation.value = (lTile.elevationEast + lTile.elevationNorth + lTile.elevationSouth + lTile.elevationWest) * 0.25;
			}
		}
		
		private function setPerspective (obj:Object) :void {
			if (mr.currentPerspective != null){
				isoMap.perspective = mr.currentPerspective;
			}else{
				isoMap.perspective = new IsoPerspective();
			}
		}
		private function btnCreateObject(e:MouseEvent) : void {
			dispatch(new EventCreateNewLibraryItem(EventCreateNewLibraryItem.CREATE_NEW_TILE));
		}
		
		private function btnRemoveObject(e:MouseEvent) : void {
			Alert.show("Are you sure you want to delete selected tiles?","Delete Tiles", Alert.YES | Alert.NO, null, removeSelectedObjects);
		}
		private function removeSelectedObjects(e:CloseEvent) : void {
			if ((e.detail & Alert.YES) > 0){
				if (v.list.selectedItem != null) {
					dispatch(new EventRemoveLibraryItems(EventRemoveLibraryItems.REMOVE_LIBRARY_ITEM, v.list.selectedItems));
				}
			}
		}
		
		private function listSelectionChange(e:IndexChangeEvent = null) : void {
			if (v.list.selectedIndex > -1 && v.list.selectedItem && v.list.selectedIndices.length == 1){
				isoMap.visible = true;
				
				isoTile.libraryReference = (v.list.selectedItem as LTile);
				isoTile.drawHeight = true;
				
				var i:uint;
				for (i = 0; i < lObjectControls.length; i++){
					Util.getPropertyToControl(v.list.selectedItem, lObjectControls[i] as UIComponent);
				}
				for (i = 0; i < objectControls.length; i++){
					Util.getPropertyToControl(isoTile, objectControls[i] as UIComponent);
				}
				updateElevationControl();
			}else{
				isoMap.visible = false;
			}
		}
		
		private function lObjectPropertyChange(e:Event = null) : void {
			var lTile:LTile = v.list.selectedItem;
			if (lTile != null){
				
				//if size changes and the object is centered, keep it centered
				if ((lTile.xSize == -lTile.deltaX) && (lTile.ySize == -lTile.deltaY)) {
					if (e.target == v.xSize) {
						v.deltaX.value = -v.xSize.value;
						dispatch(new EventSetLibraryItemProperty(EventSetLibraryItemProperty.CHANGE_LIBRARY_ITEM_PROPERTY, 
							lTile, v.deltaX.name, Util.getControlValue(v.deltaX as UIComponent)));
					}
					if (e.target == v.ySize){
						v.deltaY.value = -v.ySize.value;
						dispatch(new EventSetLibraryItemProperty(EventSetLibraryItemProperty.CHANGE_LIBRARY_ITEM_PROPERTY, 
							lTile, v.deltaY.name, Util.getControlValue(v.deltaY as UIComponent)));
					}
				}
				
				dispatch(new EventSetLibraryItemProperty(EventSetLibraryItemProperty.CHANGE_LIBRARY_ITEM_PROPERTY, 
					lTile, e.target.name, Util.getControlValue(e.target as UIComponent)));
				if (e.target == v.imagesList && e.type == Event.CHANGE){
					setTimeout(setDefaultImageCoordinates, 300);
				}
				if (e.target == v.elevationEast || e.target == v.elevationNorth || e.target == v.elevationSouth || e.target == v.elevationWest) {
					updateElevationControl();
				}
			}
		}
		
		private function setDefaultImageCoordinates() : void {
			v.imageX.value = -isoTile.image.width / 2;
			v.imageY.value = 0;
		}
		
		private function objectPropertyChange(e:Event = null) : void {
			Util.setCascadePropery(isoTile, (e.target as UIComponent).name, Util.getControlValue(e.target as UIComponent));
		}
	}
}